home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cocktail
/
puma.lha
/
puma
/
src
/
c.puma
< prev
next >
Wrap
Text File
|
1992-09-25
|
29KB
|
1,143 lines
/* Ich, Doktor Josef Grosch, Informatiker, 21.6.1991 */
TRAFO C
TREE Tree
PUBLIC DefC ImplC MacroC
GLOBAL {
FROM Positions IMPORT tPosition;
FROM IO IMPORT StdOutput, WriteS, WriteNl;
FROM Strings IMPORT tString, IntToString, Concatenate, ArrayToString;
FROM StringMem IMPORT WriteString;
FROM Idents IMPORT tIdent, NoIdent, MakeIdent;
FROM Texts IMPORT WriteText;
FROM Sets IMPORT IsElement, IsNotEqual, Minimum, Maximum, IsEmpty;
FROM Semantics IMPORT IdentifyVar, UserTypes, LookupClass;
FROM Optimize IMPORT NeedsTempo, NeedsMatch, NeedsNoFinale, GetRule;
FROM Tree IMPORT NoTree, tTree, Options, f, SourceFile, WI, WN;
VAR
RoutineKind : (kProcedure, kFunction, kPredicate);
WithCount ,
RuleCount ,
ListCount : INTEGER;
i, j : CARDINAL;
rule ,
TheClass ,
InFormals ,
OutFormals ,
ReturnFormals,
Decls : tTree;
TheName : tIdent;
TemposDone : BOOLEAN;
PROCEDURE WriteLine (Line: tPosition);
BEGIN
IF Line.Line # 0 THEN
IF IsElement (ORD ('6'), Options) THEN
!# line ! WN (Line.Line); @ "@ WriteS (f, SourceFile); @"@
ELSE
!/* line ! WN (Line.Line); @ "@ WriteS (f, SourceFile); @" */@
END;
END;
END WriteLine;
PROCEDURE Match (t, Formals: tTree);
VAR TreeName : tIdent;
VAR Pattern : tTree;
BEGIN
IF (t^.Kind = Tree.NoPattern) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
Pattern := t^.OnePattern.Pattern;
CASE Pattern^.Kind OF
| Tree.Decompose: WITH Pattern^.Decompose DO
TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) OR
IsNotEqual (Object^.Class.TypeDesc^.NodeTypes.Types, Formals^.Formal.TypeDesc^.NodeTypes.Types) THEN
IF Object^.Class.Extensions^.Kind = Tree.NoClass THEN (* Low ? *)
@ if (@ ImplC (Path); @->Kind != k@ WI (Object^.Class.Name);
ELSE
@ if (! @ WI (TreeName); @_IsType (@ ImplC (Path); @, k@ WI (Object^.Class.Name); @)@
END;
!) goto yyL! WN (RuleCount); !;!
END;
Match (Patterns, Object^.Class.Formals);
END;
| Tree.VarDef: WITH Pattern^.VarDef DO
IF Object # NoTree THEN
WITH Object^.Formal DO
@ if (! (equal@ DefC (TypeDesc); @ (@ ImplC (Path);
!, ! ImplC (Pattern^.VarDef.Path); !))) goto yyL! WN (RuleCount); !;!
END;
END;
END;
| Tree.NilTest:
! if (! ImplC (Pattern^.NilTest.Path); @ != NULL) goto yyL@ WN (RuleCount); !;!
| Tree.DontCare1:
| Tree.DontCare: RETURN;
| Tree.Value: WITH Pattern^.Value DO
AssignTempo (Expr);
IF (Formals^.Formal.TypeDesc^.Kind = Tree.UserType) AND
IsElement (Formals^.Formal.TypeDesc^.UserType.Type, UserTypes) THEN
! {! DefC (Formals^.Formal.TypeDesc); ! yyT; yyT = ! Expression (Expr); !;!
@ if (! (equal@ DefC (Formals^.Formal.TypeDesc);
! (! ImplC (Path); !, yyT))) goto yyL! WN (RuleCount); !;!
! }!
ELSE
@ if (! (equal@ DefC (Formals^.Formal.TypeDesc);
! (! ImplC (Path); !, ! Expression (Expr); !))) goto yyL! WN (RuleCount); !;!
END;
MatchExpr (Expr);
END;
END;
Match (t^.OnePattern.Next, Formals^.Formal.Next);
END Match;
PROCEDURE MatchExprs (t: tTree);
BEGIN
IF t^.Kind = Tree.NoExpr THEN RETURN; END;
IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
MatchExpr (t^.OneExpr.Expr);
MatchExprs (t^.OneExpr.Next);
END MatchExprs;
PROCEDURE MatchExpr (t: tTree);
BEGIN
CASE t^.Kind OF
| Tree.Compose:
MatchExprs (t^.Compose.Exprs);
| Tree.VarUse :
| Tree.Nil :
| Tree.DontCare1 :
| Tree.TargetExpr :
| Tree.StringExpr :
| Tree.AttrDesc :
| Tree.Call : WITH t^.Call DO
MatchExpr (Expr);
MatchExprs (Exprs);
IF Object # NoTree THEN
Match (Patterns, Object^.Routine.OutForm);
END;
END;
| Tree.Binary : WITH t^.Binary DO
MatchExpr (Lop);
MatchExpr (Rop);
END;
| Tree.PreOperator, Tree.PostOperator :
MatchExpr (t^.PreOperator.Expr);
| Tree.Index :
MatchExpr (t^.Index.Expr);
MatchExprs (t^.Index.Exprs);
| Tree.Parents :
MatchExpr (t^.Parents.Expr);
END;
END MatchExpr;
PROCEDURE AssignTempos (t: tTree);
BEGIN
IF t^.Kind = Tree.NoExpr THEN RETURN; END;
IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN RETURN; END;
AssignTempo (t^.OneExpr.Expr);
AssignTempos (t^.OneExpr.Next);
END AssignTempos;
PROCEDURE AssignTempo (t: tTree);
VAR TreeName : tIdent;
BEGIN
CASE t^.Kind OF
| Tree.Compose: WITH t^.Compose DO
TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
! yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,!
WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
!_NodeSize,Make! WI (TreeName); !,! WI (Tempo); !,k! WI (Object^.Class.Name); !)!
AssignSubFormals (Exprs, Object^.Class.Formals, Tempo, Object^.Class.Name);
END;
| Tree.VarUse :
| Tree.Nil :
| Tree.DontCare1 :
| Tree.TargetExpr :
| Tree.StringExpr :
| Tree.AttrDesc :
| Tree.Call : WITH t^.Call DO
AssignTempo (Expr);
AssignTempos (Exprs);
END;
| Tree.Binary : WITH t^.Binary DO
AssignTempo (Lop);
AssignTempo (Rop);
END;
| Tree.PreOperator, Tree.PostOperator :
AssignTempo (t^.PreOperator.Expr);
| Tree.Index :
AssignTempo (t^.Index.Expr);
AssignTempos (t^.Index.Exprs);
| Tree.Parents :
AssignTempo (t^.Parents.Expr);
END;
END AssignTempo;
PROCEDURE AssignFormals (t, Formals: tTree);
BEGIN
IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
BeginFormals (Formals);
RETURN;
END;
AssignFormal (t^.OneExpr.Expr, Formals);
MatchExpr (t^.OneExpr.Expr);
AssignFormals (t^.OneExpr.Next, Formals^.Formal.Next);
END AssignFormals;
PROCEDURE AssignFormal (t, Formals: tTree);
VAR TreeName, With : tIdent;
BEGIN
IF t^.Kind = Tree.Compose THEN
WITH t^.Compose DO
TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
With := MakeWith ();
! {register t! WI (TreeName); ! ! WI (With); !;!
! yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,!
WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
!_NodeSize,Make! WI (TreeName); !,! WI (With); !,k! WI (Object^.Class.Name); !)!
! * ! WI (Formals^.Formal.Name); ! = ! WI (With); !;!
AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
! }!
END;
ELSE
AssignTempo (t);
END;
CASE t^.Kind OF
| Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
Tree.AttrDesc:
! * ! WI (Formals^.Formal.Name); ! = ! Expression (t); !;!
| Tree.DontCare1:
! begin! DefC (Formals^.Formal.TypeDesc); ! (* ! WI (Formals^.Formal.Name); !)!
ELSE
END;
END AssignFormal;
PROCEDURE AssignSubFormals (t, Formals: tTree; PrevWith, Composer: tIdent);
BEGIN
IF (t^.Kind = Tree.NoExpr) OR (Formals^.Kind # Tree.Formal) THEN RETURN; END;
IF t^.OneExpr.Expr^.Kind = Tree.DontCare THEN
BeginSubFormals (Formals, PrevWith, Composer);
RETURN;
END;
AssignSubFormal (t^.OneExpr.Expr, Formals, PrevWith, Composer);
AssignSubFormals (t^.OneExpr.Next, Formals^.Formal.Next, PrevWith, Composer);
END AssignSubFormals;
PROCEDURE AssignSubFormal (t, Formals: tTree; PrevWith, Composer: tIdent);
VAR TreeName, With : tIdent;
BEGIN
IF t^.Kind = Tree.Compose THEN
WITH t^.Compose DO
TreeName := Object^.Class.TypeDesc^.NodeTypes.TreeName^.TreeName.Name;
With := MakeWith ();
! {register t! WI (TreeName); ! ! WI (With); !;!
! yyALLOC (t! WI (TreeName); !,! WI (TreeName); !_PoolFreePtr,!
WI (TreeName); !_PoolMaxPtr,! WI (TreeName); !_Alloc,! WI (TreeName);
!_NodeSize,Make! WI (TreeName); !,! WI (With); !,k! WI (Object^.Class.Name); !)!
! ! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); ! = ! WI (With); !;!
AssignSubFormals (Exprs, Object^.Class.Formals, With, Object^.Class.Name);
! }!
END;
ELSE
AssignTempo (t);
END;
CASE t^.Kind OF
| Tree.VarUse, Tree.Nil, Tree.Call, Tree.Binary, Tree.PreOperator,
Tree.PostOperator, Tree.Index, Tree.Parents, Tree.TargetExpr, Tree.StringExpr,
Tree.AttrDesc:
! ! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); ! = ! Expression (t); !;!
| Tree.DontCare1:
! begin! DefC (Formals^.Formal.TypeDesc); ! (! WI (PrevWith); !->! WI (Composer); !.! WI (Formals^.Formal.Name); !)!
ELSE
END;
END AssignSubFormal;
PROCEDURE BeginFormals (Formals: tTree);
BEGIN
IF Formals^.Kind = Tree.Formal THEN
WITH Formals^.Formal DO
! begin! DefC (TypeDesc); ! (* ! WI (Name); !)!
BeginFormals (Next);
END;
END;
END BeginFormals;
PROCEDURE BeginSubFormals (Formals: tTree; PrevWith, Composer: tIdent);
BEGIN
IF Formals^.Kind = Tree.Formal THEN
WITH Formals^.Formal DO
! begin! DefC (TypeDesc); ! (! WI (PrevWith); !->! WI (Composer); !.! WI (Name); !)!
BeginSubFormals (Next, PrevWith, Composer);
END;
END;
END BeginSubFormals;
PROCEDURE ConsPatterns (t: tTree; ListCount: INTEGER): INTEGER;
BEGIN
IF t^.Kind = Tree.NoPattern THEN RETURN ListCount; END;
WITH t^.OnePattern DO
IF Pattern^.Kind = Tree.DontCare THEN
RETURN ConsTempos (Pattern^.DontCare.Tempos, ListCount, TRUE);
ELSE
IF ListCount > 0 THEN !, ! END;
!& ! WI (Pattern^.Pattern.Tempo);
RETURN ConsPatterns (Next, ListCount + 1);
END;
END;
END ConsPatterns;
PROCEDURE ConsTempos (t: tTree; ListCount: INTEGER; IsRef: BOOLEAN): INTEGER;
BEGIN
IF t^.Kind = Tree.Formal THEN
IF ListCount > 0 THEN !, ! END;
IF IsRef THEN !& ! END;
WI (t^.Formal.Name);
RETURN ConsTempos (t^.Formal.Next, ListCount + 1, IsRef);
ELSE
RETURN ListCount;
END;
END ConsTempos;
PROCEDURE Expressions (t: tTree; ListCount: INTEGER): INTEGER;
BEGIN
IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
WITH t^.OneExpr DO
IF Expr^.Kind = Tree.DontCare THEN
RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
ELSE
IF ListCount > 0 THEN !, ! END;
Expression (Expr);
RETURN Expressions (Next, ListCount + 1);
END;
END;
END Expressions;
PROCEDURE Expressions2 (t: tTree; ListCount: INTEGER; Formals: tTree): INTEGER;
BEGIN
IF t^.Kind = Tree.NoExpr THEN RETURN ListCount; END;
WITH t^.OneExpr DO
IF Expr^.Kind = Tree.DontCare THEN
RETURN ConsTempos (Expr^.DontCare.Tempos, ListCount, FALSE);
ELSE
IF ListCount > 0 THEN !, ! END;
IF Formals^.Formal.Path^.Var.IsOutput THEN !& ! END;
Expression (Expr);
RETURN Expressions2 (Next, ListCount + 1, Formals^.Formal.Next);
END;
END;
END Expressions2;
PROCEDURE Expression (t: tTree);
BEGIN
CASE t^.Kind OF
| Tree.Compose : WI (t^.Compose.Tempo);
| Tree.Nil : !NULL!
| Tree.VarUse : WITH t^.VarUse DO
IF Object # NoTree THEN
ImplC (Object^.Formal.Path);
ELSE
WI (Name);
END;
END;
| Tree.DontCare1 : WI (t^.DontCare1.Tempo);
| Tree.Call : WITH t^.Call DO
Expression (Expr); ! (!
IF Object # NoTree THEN
ListCount := Expressions2 (Exprs, 0, Object^.Routine.InForm);
ListCount := ConsPatterns (Patterns, ListCount);
ELSE
ListCount := Expressions (Exprs, 0);
ListCount := Expressions (Patterns, ListCount);
END;
!)!
END;
| Tree.Binary : WITH t^.Binary DO
Expression (Lop); ! ! WI (Operator); ! ! Expression (Rop);
END;
| Tree.PreOperator :
WI (t^.PreOperator.Operator); ! ! Expression (t^.PreOperator.Expr);
| Tree.PostOperator :
Expression (t^.PostOperator.Expr); ! ! WI (t^.PostOperator.Operator);
| Tree.Index :
Expression (t^.Index.Expr); ! [! ListCount := Expressions (t^.Index.Exprs, 0); !]!
| Tree.Parents : !(! Expression (t^.Parents.Expr); !)!
| Tree.TargetExpr : ImplC (t^.TargetExpr.Expr);
| Tree.StringExpr : WriteString (f, t^.StringExpr.String);
| Tree.AttrDesc : WITH t^.AttrDesc DO
ImplC (Object^.Formal.Path); !->! WI (Type); !.! WI (Attribute);
END;
END;
END Expression;
PROCEDURE MakeWith (): tIdent;
VAR String1, String2 : tString;
BEGIN
INC (WithCount);
ArrayToString ("yyW", String1);
IntToString (WithCount, String2);
Concatenate (String1, String2);
RETURN MakeIdent (String1);
END MakeWith;
}
PROCEDURE MacroC (t: Tree)
Spec (..) :- {
MacroC (TreeNames);
}; .
TreeName (..) :- {
!# define begint! WI (Name); !(a) a = NULL;!
!# define equalt! WI (Name); !(a, b) IsEqual! WI (Name); ! (a, b)!
MacroC (Next);
}; .
PROCEDURE DefC (t: Tree)
Spec (..) :- {
!# ifndef yy! WI (TrafoName); !!
!# define yy! WI (TrafoName); !!
!!
!# if defined __STDC__ | defined __cplusplus!
!# define ARGS(parameters) parameters!
!# else!
!# define ARGS(parameters) ()!
!# endif!
!!
!# ifndef bool!
!# define bool char!
!# endif!
!!
DefC (TreeNames);
!!
WriteLine (Codes^.Codes.ImportLine);
WriteText (f, Codes^.Codes.Import);
WriteLine (Codes^.Codes.ExportLine);
WriteText (f, Codes^.Codes.Export);
!!
!extern void (* ! WI (TrafoName); !_Exit) ();!
!!
DefC (Public);
!!
!extern void Begin! WI (TrafoName); ! ();!
!extern void Close! WI (TrafoName); ! ();!
!!
!# endif!
}; .
TreeName (..) :- {
@# include "@ WI (Name); @.h"@
DefC (Next);
}; .
Name (..) :- {
IF Object # NoTree THEN
ListCount := 0;
!extern !
IF Object^.Kind = Tree.Procedure THEN
!void!
ELSIF Object^.Kind = Tree.Function THEN
DefC (Object^.Function.ReturnForm^.Formal.TypeDesc);
ELSIF Object^.Kind = Tree.Predicate THEN
!bool!
END;
! ! WI (Name); ! ARGS((!
DefC (Object^.Routine.InForm);
DefC (Object^.Routine.OutForm);
!));!
END;
DefC (Next);
}; .
Formal (..) :- {
IF ListCount > 0 THEN !, ! END;
DefC (TypeDesc);
IF Path^.Var.IsOutput THEN ! *! END;
! ! WI (Name);
INC (ListCount);
DefC (Next);
}; .
NodeTypes (..) :- {
!t! WI (TreeName^.TreeName.Name);
}; .
UserType (..) :- {
WI (Type);
}; .
PROCEDURE Forward (t: Tree)
Procedure (..) :- {
ListCount := 0;
IF NOT IsExtern THEN !static ! END;
!void ! WI (Name); ! ARGS((!
DefC (InForm);
DefC (OutForm);
!));!
Forward (Next);
}; .
Function (..) :- {
ListCount := 0;
IF NOT IsExtern THEN !static ! END;
DefC (ReturnForm^.Formal.TypeDesc); ! ! WI (Name); ! ARGS((!
DefC (InForm);
DefC (OutForm);
!));!
Forward (Next);
}; .
Predicate (..) :- {
ListCount := 0;
IF NOT IsExtern THEN !static ! END;
!bool ! WI (Name); ! ARGS((!
DefC (InForm);
DefC (OutForm);
!));!
Forward (Next);
}; .
PROCEDURE ProcHead1 (t: Tree)
Formal (..) :- {
IF ListCount > 0 THEN !, ! END;
WI (Name);
INC (ListCount);
ProcHead1 (Next);
}; .
PROCEDURE ProcHead2 (t: Tree)
Formal (..) :- {
! !
IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN !register ! END;
ImplC (TypeDesc); IF Path^.Var.IsOutput THEN ! *! END; ! ! WI (Name); !;!
ProcHead2 (Next);
}; .
PROCEDURE ProcHead3 (t: Tree)
Formal (..) :- {
IF ListCount > 0 THEN !, ! END;
IF (TypeDesc^.Kind = Tree.NodeTypes) AND Path^.Var.IsRegister THEN !register ! END;
ImplC (TypeDesc); IF Path^.Var.IsOutput THEN ! *! END; ! ! WI (Name);
INC (ListCount);
ProcHead3 (Next);
}; .
PROCEDURE ImplC (t: Tree)
Spec (..) :- {
@# include "@ WI (TrafoName); @.h"@
!# ifdef __cplusplus!
@extern "C" {@
@# include "System.h"@
!}!
!# else!
@# include "System.h"@
!# endif!
!# include <stdio.h>!
DefC (TreeNames);
!!
IF NOT IsElement (ORD ('m'), Options) THEN
!# define yyInline!
END;
!# ifndef NULL!
!# define NULL 0L!
!# endif!
!# ifndef false!
!# define false 0!
!# endif!
!# ifndef true!
!# define true 1!
!# endif!
!!
!# ifdef yyInline!
!# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) \!
! if ((ptr = (tree) free) >= (tree) max) ptr = alloc (); \!
! free += nodesize [kind]; \!
! ptr->yyHead.yyMark = 0; \!
! ptr->Kind = kind;!
!# else!
!# define yyALLOC(tree, free, max, alloc, nodesize, make, ptr, kind) ptr = make (kind);!
!# endif!
!!
!# define yyWrite(s) (void) fputs (s, yyf)!
!# define yyWriteNl (void) fputc ('\n', yyf)!
!!
WriteLine (Codes^.Codes.GlobalLine);
WriteText (f, Codes^.Codes.Global);
@# include "yy@ WI (TrafoName); @.w"@
!!
!static void yyExit () { Exit (1); }!
!!
!void (* ! WI (TrafoName); !_Exit) () = yyExit;!
!!
!static FILE * yyf = stdout;!
!!
!static void yyAbort!
!# ifdef __cplusplus!
! (char * yyFunction)!
!# else!
! (yyFunction) char * yyFunction;!
!# endif!
!{!
@ (void) fprintf (stderr, "Error: module @ WI (TrafoName); @, routine %s failed\n", yyFunction);@
! ! WI (TrafoName); !_Exit ();!
!}!
!!
Forward (Routines);
!!
ImplC (Routines);
!void Begin! WI (TrafoName); ! ()!
!{!
WriteLine (Codes^.Codes.BeginLine);
WriteText (f, Codes^.Codes.Begin);
!}!
!!
!void Close! WI (TrafoName); ! ()!
!{!
WriteLine (Codes^.Codes.CloseLine);
WriteText (f, Codes^.Codes.Close);
!}!
}; .
Procedure (..) :- {
IF NOT IsExtern THEN !static ! END;
!void ! WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
ListCount := 0;
!(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
!# else!
ListCount := 0;
!(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
ProcHead2 (InForm);
ProcHead2 (OutForm);
!# endif!
!{!
WriteLine (LocalLine);
WriteText (f, Local);
RoutineKind := kProcedure;
InFormals := InForm;
OutFormals := OutForm;
IF IsElement (ORD ('n'), Options) THEN
Tg1 (InForm);
END;
IF IsElement (ORD ('b'), Options) THEN
ImplC (Rules);
IF IsElement (ORD ('f'), Options) THEN
@ yyAbort ("@ WI (Name); @");@
END;
ELSE
TemposDone := FALSE;
CommonTestElim (Decisions);
IF IsElement (ORD ('f'), Options) AND NOT NeedsNoFinale (Decisions) THEN
@ yyAbort ("@ WI (Name); @");@
END;
END;
!;!
!}!
!!
ImplC (Next);
}; .
Function (..) :- {
IF NOT IsExtern THEN !static ! END;
DefC (ReturnForm^.Formal.TypeDesc); ! ! WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
ListCount := 0;
!(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
!# else!
ListCount := 0;
!(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
ProcHead2 (InForm);
ProcHead2 (OutForm);
!# endif!
!{!
WriteLine (LocalLine);
WriteText (f, Local);
RoutineKind := kFunction;
InFormals := InForm;
OutFormals := OutForm;
ReturnFormals := ReturnForm;
IF IsElement (ORD ('b'), Options) THEN
ImplC (Rules);
@ yyAbort ("@ WI (Name); @");@
ELSE
TemposDone := FALSE;
CommonTestElim (Decisions);
IF NOT NeedsNoFinale (Decisions) THEN
@ yyAbort ("@ WI (Name); @");@
END;
END;
!}!
!!
ImplC (Next);
}; .
Predicate (..) :- {
IF NOT IsExtern THEN !static ! END;
!bool ! WI (Name); !!
!# if defined __STDC__ | defined __cplusplus!
ListCount := 0;
!(! ProcHead3 (InForm); ProcHead3 (OutForm); !)!
!# else!
ListCount := 0;
!(! ProcHead1 (InForm); ProcHead1 (OutForm); !)!
ProcHead2 (InForm);
ProcHead2 (OutForm);
!# endif!
!{!
WriteLine (LocalLine);
WriteText (f, Local);
RoutineKind := kPredicate;
InFormals := InForm;
OutFormals := OutForm;
IF IsElement (ORD ('n'), Options) THEN
Tg1 (InForm);
END;
IF IsElement (ORD ('b'), Options) THEN
ImplC (Rules);
! return false;!
ELSE
TemposDone := FALSE;
CommonTestElim (Decisions);
IF NOT NeedsNoFinale (Decisions) THEN
! return false;!
END;
END;
!}!
!!
ImplC (Next);
}; .
Rule (..) :- {
WriteLine (Line);
IF HasTempos THEN ! {!
END;
RuleCount := Index;
WithCount := 0;
Decls := VarDecls;
Declare (Patterns);
Declare (Exprs);
Declare (Statements);
Match (Patterns, InFormals);
IF Statements^.Kind # Tree.NoStatement THEN
! {!
ImplC (Statements);
! }!
END;
IF NOT HasRejectOrFail THEN
AssignFormals (Exprs, OutFormals);
CASE RoutineKind OF
| kProcedure: ! return;!
| kFunction :
IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
! {register ! DefC (ReturnFormals^.Formal.TypeDesc); ! ! WI (Tempo); !;!
Declare (Expr);
AssignTempo (Expr);
! ! WI (Tempo); ! = ! Expression (Expr); !;!
MatchExpr (Expr);
! return ! WI (Tempo); !;!
! }!
ELSIF HasTempos THEN
! {!
Declare (Expr);
AssignTempo (Expr);
MatchExpr (Expr);
! return ! Expression (Expr); !;!
! }!
ELSE
! return ! Expression (Expr); !;!
END;
| kPredicate: ! return true;!
END;
END;
IF HasTempos THEN ! }!
END;
!yyL! WN (RuleCount); !:;!
!!
ImplC (Next);
}; .
ProcCall (..) :- {
WriteLine (Pos);
AssignTempo (Call);
! ! Expression (Call); !;!
MatchExpr (Call);
ImplC (Next);
}; .
Condition (..) :- {
WriteLine (Pos);
AssignTempo (Expr);
@ if (! (@ Expression (Expr); @)) goto yyL@ WN (RuleCount); @;@
MatchExpr (Expr);
IF Next^.Kind # Tree.NoStatement THEN
! {!
ImplC (Next);
! }!
END;
}; .
Assignment (..) :- {
WriteLine (Pos);
AssignTempo (Adr);
AssignTempo (Expr);
IF Object # NoTree THEN
! ! ImplC (Object^.Formal.Path);
ELSE
! ! Expression (Adr);
END;
! = ! Expression (Expr); !;!
MatchExpr (Adr);
MatchExpr (Expr);
ImplC (Next);
}; .
Reject (..) :- {
WriteLine (Pos);
! goto yyL! WN (RuleCount); !;!
}; .
Fail (..) :- {
WriteLine (Pos);
! return! IF RoutineKind = kPredicate THEN ! false! END; !;!
}; .
TargetStmt (..) :- {
WriteLine (Pos);
ImplC (Stmt); !!
ImplC (Next);
}; .
Nl (..) :- {
WriteLine (Pos);
! yyWriteNl;!
ImplC (Next);
}; .
WriteStr (..) :- {
WriteLine (Pos);
! yyWrite (! WriteString (f, String); !);!
ImplC (Next);
}; .
Ident (..) :- Var: tTree; {
Var := IdentifyVar (Decls, Attribute);
IF Var # NoTree THEN ImplC (Var^.Formal.Path); ELSE WI (Attribute); END;
ImplC (Next);
}; .
Any (..) :- {
WriteString (f, Code);
ImplC (Next);
}; .
Anys (..) :- {
ImplC (Layouts);
ImplC (Next);
}; .
LayoutAny (..) :- {
WriteString (f, Code);
ImplC (Next);
}; .
Designator (..) :- {
ImplC (Object^.Formal.Path); !->! WI (Type); !.! WI (Attribute);
ImplC (Next);
}; .
Field (..) :- {
ImplC (Next);
!.! WI (Name);
}; .
ConsType (..) :- {
ImplC (Next);
!->! WI (Name);
}; .
Var (..) :- {
IF IsOutput THEN
!(* ! WI (Name); !)!
ELSE
WI (Name);
END;
}; .
NodeTypes (..) :- {
!t! WI (TreeName^.TreeName.Name);
}; .
UserType (..) :- {
IF NOT IsElement (Type, UserTypes) THEN !register ! END; WI (Type);
}; .
PROCEDURE Declare (t: Tree) /* reads GLOBAL Decls */
Formal (..) :- {
! ! DefC (TypeDesc); ! ! WI (Name); !;!
Declare (Next);
}; .
Param (..) :- Var: tTree; {
Var := IdentifyVar (Decls, Name);
! ! DefC (Var^.Formal.TypeDesc); ! ! WI (Name); !;!
Declare (Next);
}; .
ProcCall (..) :- {
Declare (Call);
Declare (Next);
}; .
Condition (..) :- {
Declare (Expr);
Declare (Next);
}; .
Assignment (..) :- {
Declare (Adr);
Declare (Expr);
Declare (Next);
}; .
TargetStmt (..) :- {
Declare (Parameters);
Declare (Next);
}; .
Statement (..) :- {
Declare (Next);
}; .
OnePattern (..) :- {
IF (Pattern^.Pattern.Tempo # NoIdent) AND (Pattern^.Kind # Tree.DontCare1) THEN
! ! DefC (Pattern^.Pattern.TypeDesc); ! ! WI (Pattern^.Pattern.Tempo); !;!
END;
Declare (Pattern);
Declare (Next);
}; .
OneExpr (..) :- {
Declare (Expr);
Declare (Next);
}; .
Decompose (..) :- {
Declare (Patterns);
}; .
DontCare (..) :- {
Declare (Tempos);
}; .
DontCare1 (..) :- {
IF Tempo # NoIdent THEN
! ! DefC (TypeDesc); ! ! WI (Tempo); !;!
END;
}; .
Value (..) :- {
Declare (Expr);
}; .
Compose (..) :- {
IF Tempo # NoIdent THEN
! register ! DefC (TypeDesc); ! ! WI (Tempo); !;!
END;
Declare (Exprs);
}; .
Call (..) :- {
Declare (Expr);
Declare (Exprs);
Declare (Patterns);
}; .
Binary (..) :- {
Declare (Lop);
Declare (Rop);
}; .
PreOperator (..) ;
PostOperator (..) ;
Parents (..) :- {
Declare (Expr);
}; .
Index (..) :- {
Declare (Expr);
Declare (Exprs);
}; .
PROCEDURE Tg1 (t: Tree)
Formal (..) :- {
TheName := Name;
Tg1 (TypeDesc);
Tg1 (Next);
}; .
NodeTypes (..) :- {
! if (! WI (TheName); ! == No! WI (TreeName^.TreeName.Name);
!) return! IF RoutineKind = kPredicate THEN ! false! END; !;!
}; .
PROCEDURE CommonTestElim (t: Tree)
Decision (..) :- {
IF Cases = 0 THEN
IF NOT TemposDone AND (OneTest^.Kind = Tree.TestValue) AND NeedsTempo (Then, rule) THEN
! {!
TemposDone := TRUE;
WITH rule^.Rule DO
RuleCount := Index;
Decls := VarDecls;
Declare (Patterns);
Declare (Exprs);
Declare (Statements);
END;
CommonTestElim (OneTest);
CommonTestElim (Then);
! }!
! }!
ELSE
GetRule (Then, rule);
Decls := rule^.Rule.VarDecls;
CommonTestElim (OneTest);
CommonTestElim (Then);
! }!
END;
IF (OneTest^.Kind = Tree.TestValue) AND
(OneTest^.TestValue.TypeDesc^.Kind = Tree.UserType) AND
IsElement (OneTest^.TestValue.TypeDesc^.UserType.Type, UserTypes) THEN
! }!
END;
TemposDone := FALSE;
CommonTestElim (Else);
ELSE
i := Cases; Case (t);
END;
}; .
Decided (..) :- {
CommonTestElim (Rule);
IF Rule^.Rule.HasExit THEN
TemposDone := FALSE;
CommonTestElim (Else);
END;
}; .
TestKind (..) :- {
! if (! ImplC (Path); !->Kind == k! WI (Name); !) {!
}; .
TestIsType (..) :- {
! if (! WI (TypeDesc^.NodeTypes.TreeName^.TreeName.Name); !_IsType (! ImplC (Path);
!, k! WI (Name); !)) {!
}; .
TestNil (..) :- {
! if (! ImplC (Path); ! == NULL) {!
}; .
TestNonlin (..) :- {
! if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, ! ImplC (Path2); !)) {!
}; .
TestValue (_, _, _, UserType (Type)) :-
(IsElement (Type, UserTypes));
{
AssignTempo (Expr);
! {! DefC (TypeDesc); ! yyT; yyT = ! Expression (Expr); !;!
MatchExpr (Expr);
! if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, yyT)) {!
}; .
TestValue (..) :- {
AssignTempo (Expr);
! if (equal! DefC (TypeDesc); ! (! ImplC (Path); !, ! Expression (Expr); !)) {!
MatchExpr (Expr);
}; .
Rule (..) :- {
WriteLine (Line);
RuleCount := Index;
WithCount := 0;
Decls := VarDecls;
IF HasTempos AND NOT TemposDone THEN ! {!
Declare (Patterns);
Declare (Exprs);
Declare (Statements);
END;
IF Statements^.Kind # Tree.NoStatement THEN
! {!
ImplC (Statements);
! }!
END;
IF NOT HasRejectOrFail THEN
AssignFormals (Exprs, OutFormals);
CASE RoutineKind OF
| kProcedure: ! return;!
| kFunction :
IF HasPatterns AND (Expr^.Kind # Tree.Compose) AND (t^.Kind # Tree.DontCare1) THEN
! {register ! DefC (ReturnFormals^.Formal.TypeDesc); ! ! WI (Tempo); !;!
Declare (Expr);
AssignTempo (Expr);
! ! WI (Tempo); ! = ! Expression (Expr); !;!
MatchExpr (Expr);
! return ! WI (Tempo); !;!
! }!
ELSIF HasTempos THEN
! {!
Declare (Expr);
AssignTempo (Expr);
MatchExpr (Expr);
! return ! Expression (Expr); !;!
! }!
ELSE
! return ! Expression (Expr); !;!
END;
| kPredicate: ! return true;!
END;
END;
IF HasTempos AND NOT TemposDone THEN ! }!
END;
IF HasExit OR NeedsMatch (Tests) THEN !yyL! WN (RuleCount); !:;!
END;
!!
}; .
PROCEDURE Case (t: Tree) /* reads GLOBAL i */
Decision (..) :- n: CARDINAL; {
!!
! switch (! ImplC (OneTest^.OneTest.Path); !->Kind) {!
n := i;
WHILE n > 0 DO
IF NOT IsEmpty (t^.Decision.OneTest^.TestIsType.TypeDesc^.NodeTypes.Types) THEN
Case (t^.Decision.OneTest);
CommonTestElim (t^.Decision.Then);
IF NOT NeedsNoFinale (t^.Decision.Then) THEN
! break;!
END;
END;
t := t^.Decision.Else;
DEC (n);
END;
! }!
!!
CommonTestElim (t);
}; .
TestKind (..) :- {
! case k! WI (Name); !:!
}; .
TestIsType (..) :- {
Case (TypeDesc);
}; .
NodeTypes (..) :- {
FOR j := Minimum (Types) TO Maximum (Types) DO
IF IsElement (j, Types) THEN
TheClass := LookupClass (TreeName^.TreeName.Classes, j);
! case k! WI (TheClass^.Class.Name); !:!
END;
END;
}; .